/*
 * Copyright (c) 2024 Shenzhen Kaihong Digital Industry Development Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include "kh_sle_ssap_client.h"
#include "kh_sle_c_interface_test_entry.h"
#include "kh_sle_host.h"
#include "kh_sle_connect.h"
#include "sle_error_code.h"
#include "sle_unit_test_log.h"
#include "stdlib.h"
SleSsapcCallbacks *g_sleSsapcUtCbs = NULL;
static SleUuid g_appUuid = {
    .len = 16,
};
static uint8_t g_clientId;
static uint16_t g_connectId;

void OnSleUtFindStructureCallback(uint8_t clientId, uint16_t connectId
        , const ClientFindServiceRes *service, SleErrorCode errCode)
{
    return;
}

static uint16_t g_propertyHandle;
void OnSleUtFindPropertyCallback(uint8_t clientId, uint16_t connectId
        , const ClientFindPropertyRes *property, SleErrorCode errCode)
{
    g_propertyHandle = property->handle;
    return;
}

void OnSleUtReadConformCallback(uint8_t clientId, uint16_t connectId
        , const ClientHandleValue *readData, SleErrorCode errCode)
{
    return;
}

void OnSleUtWriteConformCallback(uint8_t clientId, uint16_t connectId
        , const ClientWriteRes *writeResult, SleErrorCode errCode)
{
    return;
}

void OnSleUtExchangeInfoCallback(uint8_t clientId, uint16_t connectId
        , const SsapMtuInfo *exchangeInfo, SleErrorCode errCode)
{
    return;
}

void OnSleUtNotificationCallback(uint8_t clientId, uint16_t connectId
        , const ClientHandleValue *data, SleErrorCode errCode)
{
    return;
}

void OnSleUtIndicationCallback(uint8_t clientId, uint16_t connectId
        , const ClientHandleValue *data, SleErrorCode errCode)
{
    return;
}

void InitSleSsapcServiceTestLevel0(void)
{
    SleErrorCode ret = SLE_ERR_UNKNOWN;
    ret = InitSleSsapcService();
    SLE_UT_CHECK_AND_PRINT_LOG(ret == SLE_NO_ERROR, "[KhSleSsapcTest][FAILED]InitSleSsapcServiceTestLevel0 failed(%d)", ret);
}

void RegisterSsapClientCallbacksTestLevel0(void)
{
    SleErrorCode ret = SLE_ERR_UNKNOWN;
    ret = RegisterSsapClientCallbacks(g_sleSsapcUtCbs);
    SLE_UT_CHECK_AND_PRINT_LOG(ret == SLE_NO_ERROR, "[KhSleSsapcTest][FAILED]RegisterSsapClientCallbacks failed(%d)", ret);
}

void AddSspaClientTestLevel0(void)
{
    SleErrorCode ret = SLE_ERR_UNKNOWN;
    ret = AddSspaClient(&g_appUuid, &g_clientId);
    SLE_UT_CHECK_AND_PRINT_LOG(ret == SLE_NO_ERROR, "[KhSleSsapcTest][FAILED]AddSspaClientTestLevel0 failed(%d)", ret);
}

void SendWriteReqTestLevel0(void)
{
    SleErrorCode ret = SLE_ERR_UNKNOWN;
    uint8_t data[15] = {'k','h','_','s','s','a','p','c','_','t','e','s','t','0','\0'};
    ClientWriteParam writeParam = {
        .type = SLE_SSAP_PROPERTY_TYPE,
        .handle = g_propertyHandle,
        .data = data,
        .dataLength = 12,
    };
    ret = SendWriteReq(g_clientId, g_connectId, &writeParam);
    SLE_UT_CHECK_AND_PRINT_LOG(ret == SLE_NO_ERROR, "[KhSleSsapcTest][FAILED]SendWriteReqTestLevel0 failed(%d)", ret);
}

void SendWriteCmdTestLevel0(void)
{
    SleErrorCode ret = SLE_ERR_UNKNOWN;
    uint8_t data[15] = {'k','h','_','s','s','a','p','c','_','t','e','s','t','0','\0'};
    ClientWriteParam writeParam = {
        .type = SLE_SSAP_PROPERTY_TYPE,
        .handle = g_propertyHandle,
        .data = data,
        .dataLength = 12,
    }; 
    ret = SendWriteCmd(g_clientId, g_connectId, &writeParam);
    SLE_UT_CHECK_AND_PRINT_LOG(ret == SLE_NO_ERROR, "[KhSleSsapcTest][FAILED]SendWriteCmdTestLevel0 failed(%d)", ret);
}

void SendReadReqTestLevel0(void)
{
    SleErrorCode ret = SLE_ERR_UNKNOWN;
    ret = SendReadReq(g_clientId, g_connectId, g_propertyHandle, SLE_SSAP_PROPERTY_TYPE);
    SLE_UT_CHECK_AND_PRINT_LOG(ret == SLE_NO_ERROR, "[KhSleSsapcTest][FAILED]SendReadReqTestLevel0 failed(%d)", ret);
}

void RemoveClientTestLevel0(void)
{
    SleErrorCode ret = SLE_ERR_UNKNOWN;
    ret = RemoveClient(g_clientId);
    SLE_UT_CHECK_AND_PRINT_LOG(ret == SLE_NO_ERROR, "[KhSleSsapcTest][FAILED]RemoveClientTestLevel0 failed(%d)", ret);
}

void UnregisterSsapClientCallbacksTestLevel0(void)
{
    SleErrorCode ret = SLE_ERR_UNKNOWN;
    ret = UnregisterSsapClientCallbacks(g_sleSsapcUtCbs);
    SLE_UT_CHECK_AND_PRINT_LOG(ret == SLE_NO_ERROR, "[KhSleSsapcTest][FAILED]UnregisterSsapClientCallbacksTestLevel0 failed(%d)", ret);
}

void DeinitSleSsapcServiceTestLevel0(void)
{
    SleErrorCode ret = SLE_ERR_UNKNOWN;
    ret = DeinitSleSsapcService();
    SLE_UT_CHECK_AND_PRINT_LOG(ret == SLE_NO_ERROR, "[KhSleSsapcTest][FAILED]DeinitSleSsapcServiceTestLevel0 failed(%d)", ret);
}

void KhSleSsapcTestLevel0(void)
{
    SLE_UT_LOG("___KhSleSsapcTestLevel0 start");
    InitSleSsapcServiceTestLevel0();
    RegisterSsapClientCallbacksTestLevel0();
    AddSspaClientTestLevel0();
    sleep(1);
    sleep(1);
    SendWriteReqTestLevel0();
    SendWriteCmdTestLevel0();
    SendReadReqTestLevel0();
    RemoveClientTestLevel0();
    UnregisterSsapClientCallbacksTestLevel0();
    DeinitSleSsapcServiceTestLevel0();  
    SLE_UT_LOG("___KhSleSsapcTestLevel0 end");
}

void InitSleSsapcServiceTestLevel1(void)
{
    SleErrorCode ret = SLE_ERR_UNKNOWN;
    ret = InitSleSsapcService();
    SLE_UT_CHECK_AND_PRINT_LOG(ret == SLE_NO_ERROR, "[KhSleSsapcTest][FAILED]InitSleSsapcServiceTestLevel1 failed1(%d)", ret);
    //测试重复调用
    ret = InitSleSsapcService();
    SLE_UT_CHECK_AND_PRINT_LOG(ret == SLE_NO_ERROR, "[KhSleSsapcTest][FAILED]InitSleSsapcServiceTestLevel1 failed2(%d)", ret);
}

void RegisterSsapClientCallbacksTestLevel1(void)
{
    SleErrorCode ret = SLE_ERR_UNKNOWN;
    //测试入参为NULL
    ret = RegisterSsapClientCallbacks(NULL);
    SLE_UT_CHECK_AND_PRINT_LOG(ret == SLE_ERR_INVALID_PARAM, "[KhSleSsapcTest][FAILED]RegisterSsapClientCallbacksTestLevel1 failed1(%d)", ret);
    //测试重复调用
    ret = RegisterSsapClientCallbacks(g_sleSsapcUtCbs);
    SLE_UT_CHECK_AND_PRINT_LOG(ret == SLE_NO_ERROR, "[KhSleSsapcTest][FAILED]RegisterSsapClientCallbacksTestLevel1 failed2(%d)", ret);
    ret = RegisterSsapClientCallbacks(g_sleSsapcUtCbs);
    SLE_UT_CHECK_AND_PRINT_LOG(ret == SLE_NO_ERROR, "[KhSleSsapcTest][FAILED]RegisterSsapClientCallbacksTestLevel1 failed3(%d)", ret);
}

void AddSspaClientTestLevel1(void)
{
    SleErrorCode ret = SLE_ERR_UNKNOWN;
    //测试入参为NULL
    ret = AddSspaClient(NULL, &g_clientId);
    SLE_UT_CHECK_AND_PRINT_LOG(ret == SLE_ERR_INVALID_PARAM, "[KhSleSsapcTest][FAILED]AddSspaClientTestLevel1 failed1(%d)", ret);
    ret = AddSspaClient(&g_appUuid, NULL);
    SLE_UT_CHECK_AND_PRINT_LOG(ret == SLE_ERR_INVALID_PARAM, "[KhSleSsapcTest][FAILED]AddSspaClientTestLevel1 failed2(%d)", ret);
    
    ret = AddSspaClient(&g_appUuid, &g_clientId);
    SLE_UT_CHECK_AND_PRINT_LOG(ret == SLE_NO_ERROR, "[KhSleSsapcTest][FAILED]AddSspaClientTestLevel1 failed3(%d)", ret);
}

void SendWriteReqTestLevel1(void)
{
    SleErrorCode ret = SLE_ERR_UNKNOWN;
    uint8_t data[15] = {'k','h','_','s','s','a','p','c','_','t','e','s','t','0','\0'};
    ClientWriteParam writeParam = {
        .type = SLE_SSAP_PROPERTY_TYPE,
        .handle = g_propertyHandle,
        .data = data,
        .dataLength = 12,
    };
    //测试入参为NULL
    ret = SendWriteReq(g_clientId, g_connectId, NULL);
    SLE_UT_CHECK_AND_PRINT_LOG(ret == SLE_ERR_INVALID_PARAM, "[KhSleSsapcTest][FAILED]SendWriteReqTestLevel1 failed1(%d)", ret);
    //测试connectId为无效值    ret = SendWriteReq(g_clientId, g_connectId + 1, &writeParam);
    SLE_UT_CHECK_AND_PRINT_LOG(ret == SLE_ERR_INVALID_PARAM, "[KhSleSsapcTest][FAILED]SendWriteReqTestLevel1 failed2(%d)", ret);

    ret = SendWriteReq(g_clientId, g_connectId, &writeParam);
    SLE_UT_CHECK_AND_PRINT_LOG(ret == SLE_NO_ERROR, "[KhSleSsapcTest][FAILED]SendWriteReqTestLevel1 failed3(%d)", ret);
}

void SendWriteCmdTestLevel1(void)
{
    SleErrorCode ret = SLE_ERR_UNKNOWN;
    uint8_t data[15] = {'k','h','_','s','s','a','p','c','_','t','e','s','t','0','\0'};
    ClientWriteParam writeParam = {
        .type = SLE_SSAP_PROPERTY_TYPE,
        .handle = g_propertyHandle,
        .data = data,
        .dataLength = 12,
    };
    //测试入参为NULL
    ret = SendWriteCmd(g_clientId, g_connectId, NULL);
    SLE_UT_CHECK_AND_PRINT_LOG(ret == SLE_ERR_INVALID_PARAM, "[KhSleSsapcTest][FAILED]SendWriteCmdTestLevel1 failed1(%d)", ret);
    //测试connectId为无效值    ret = SendWriteCmd(g_clientId, g_connectId + 1, &writeParam);
    SLE_UT_CHECK_AND_PRINT_LOG(ret == SLE_ERR_INVALID_PARAM, "[KhSleSsapcTest][FAILED]SendWriteCmdTestLevel1 failed2(%d)", ret);

    ret = SendWriteCmd(g_clientId, g_connectId, &writeParam);
    SLE_UT_CHECK_AND_PRINT_LOG(ret == SLE_NO_ERROR, "[KhSleSsapcTest][FAILED]SendWriteCmdTestLevel1 failed3(%d)", ret);
}

void SendReadReqTestLevel1(void)
{
    SleErrorCode ret = SLE_ERR_UNKNOWN;
    uint16_t handle = 1;
    //测试connectId为无效值    
    ret = SendReadReq(g_clientId, g_connectId + 1, handle, SLE_SSAP_PROPERTY_TYPE);
    SLE_UT_CHECK_AND_PRINT_LOG(ret == SLE_ERR_INVALID_PARAM, "[KhSleSsapcTest][FAILED]SendReadReqTestLevel1 failed1(%d)", ret);
    
    ret = SendReadReq(g_clientId, g_connectId, handle, SLE_SSAP_PROPERTY_TYPE);
    SLE_UT_CHECK_AND_PRINT_LOG(ret == SLE_NO_ERROR, "[KhSleSsapcTest][FAILED]SendReadReqTestLevel1 failed2(%d)", ret);
}

void RemoveClientTestLevel1(void)
{
    SleErrorCode ret = SLE_ERR_UNKNOWN;
    //TODO:测试client为无效值    
    // ret = RemoveClient(g_clientId + 1);
    // SLE_UT_CHECK_AND_PRINT_LOG(ret == SLE_ERR_INVALID_PARAM, "[KhSleSsapcTest][FAILED]RemoveClientTestLevel1 failed1(%d)", ret);

    ret = RemoveClient(g_clientId);
    SLE_UT_CHECK_AND_PRINT_LOG(ret == SLE_NO_ERROR, "[KhSleSsapcTest][FAILED]RemoveClientTestLevel1 failed2(%d)", ret);
}

void UnregisterSsapClientCallbacksTestLevel1(void)
{
    SleErrorCode ret = SLE_ERR_UNKNOWN;
    //测试入参为NULL
    ret = UnregisterSsapClientCallbacks(NULL);
    SLE_UT_CHECK_AND_PRINT_LOG(ret == SLE_ERR_INVALID_PARAM, "[KhSleSsapcTest][FAILED]UnregisterSsapClientCallbacksTestLevel1 failed1(%d)", ret);
    //测试重复调用
    ret = UnregisterSsapClientCallbacks(g_sleSsapcUtCbs);
    SLE_UT_CHECK_AND_PRINT_LOG(ret == SLE_NO_ERROR, "[KhSleSsapcTest][FAILED]UnregisterSsapClientCallbacksTestLevel1 failed2(%d)", ret);
    ret = UnregisterSsapClientCallbacks(g_sleSsapcUtCbs);
    SLE_UT_CHECK_AND_PRINT_LOG(ret == SLE_NO_ERROR, "[KhSleSsapcTest][FAILED]UnregisterSsapClientCallbacksTestLevel1 failed3(%d)", ret);
}

void DeinitSleSsapcServiceTestLevel1(void)
{
    SleErrorCode ret = SLE_ERR_UNKNOWN;
    ret = DeinitSleSsapcService();
    SLE_UT_CHECK_AND_PRINT_LOG(ret == SLE_NO_ERROR, "[KhSleSsapcTest][FAILED]DeinitSleSsapcServiceTestLevel1 failed1(%d)", ret);
    //测试重复调用
    ret = DeinitSleSsapcService();
    SLE_UT_CHECK_AND_PRINT_LOG(ret == SLE_ERR_NOT_READY, "[KhSleSsapcTest][FAILED]DeinitSleSsapcServiceTestLevel1 failed2(%d)", ret);
}

void KhSleSsapcTestLevel1(void)
{
    SLE_UT_LOG("___KhSleSsapcTestLevel1 start");
    InitSleSsapcServiceTestLevel1();
    RegisterSsapClientCallbacksTestLevel1();
    AddSspaClientTestLevel1();
    SendWriteReqTestLevel1();
    SendWriteCmdTestLevel1();
    SendReadReqTestLevel1();
    RemoveClientTestLevel1();
    UnregisterSsapClientCallbacksTestLevel1();
    DeinitSleSsapcServiceTestLevel1();
    SLE_UT_LOG("___KhSleSsapcTestLevel1 end");
}

SleErrorCode InitKhSleSsapcTestEntry(void)
{
    SleErrorCode ret = SLE_ERR_UNKNOWN;
    g_sleSsapcUtCbs = (SleSsapcCallbacks *)malloc(sizeof(SleSsapcCallbacks));
    SLE_UT_CHECK_AND_RETURN_RET(g_sleSsapcUtCbs != NULL, SLE_ERR_SYSTEM_WRONG);
    g_sleSsapcUtCbs->OnSleFindStructureCb = OnSleUtFindStructureCallback;
    g_sleSsapcUtCbs->OnSleFindPropertyCb = OnSleUtFindPropertyCallback;
    g_sleSsapcUtCbs->OnSleReadCfmCb = OnSleUtReadConformCallback;
    g_sleSsapcUtCbs->OnSleWriteCfmCb = OnSleUtWriteConformCallback;
    g_sleSsapcUtCbs->OnSleExchangeInfoCb = OnSleUtExchangeInfoCallback;
    g_sleSsapcUtCbs->OnSleNotificatedCb = OnSleUtNotificationCallback;
    g_sleSsapcUtCbs->OnSleIndicatedCb = OnSleUtIndicationCallback;
    SleConnectDev  connectDevList[SLE_MAX_CONNECT_ID_NUM];
    uint16_t connectListLen = SLE_MAX_CONNECT_ID_NUM;
    ret = GetConnectDevList(connectDevList, &connectListLen);
    SLE_UT_CHECK_AND_RETURN_RET(ret == SLE_NO_ERROR, ret);
    g_connectId = connectDevList[0].connId;
    uint8_t uuid[UUID_LEN] = {1};
    memcpy(g_appUuid.uuid, uuid, UUID_LEN);
    ret = SLE_NO_ERROR;
    return ret;
}

SleErrorCode DeinitKhSleSsapcTestEntry(void)
{
    if (g_sleSsapcUtCbs != NULL) {
        free(g_sleSsapcUtCbs);
    }
    g_sleSsapcUtCbs = NULL;
    return SLE_NO_ERROR;
}

void KhSleSsapcTestEntry(void)
{
    SLE_UT_LOG("__KhSleSsapcTestEntry start");
    SleErrorCode ret = InitKhSleSsapcTestEntry();
    SLE_UT_CHECK_AND_RETURN_LOG(ret == SLE_NO_ERROR, "[KhSleSsapcTest][FAILED]InitKhSleSsapcTestEntry failed(%d)", ret);
    KhSleSsapcTestLevel0();
    KhSleSsapcTestLevel1();
    ret = DeinitKhSleSsapcTestEntry();
    SLE_UT_CHECK_AND_RETURN_LOG(ret == SLE_NO_ERROR, "[KhSleSsapcTest][FAILED]DeinitKhSleSsapcTestEntry failed(%d)", ret);
    SLE_UT_LOG("__KhSleSsapcTestEntry end");
}
